home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-03 | 33.6 KB | 1,391 lines | [TEXT/KAHL] |
- * ***
- * tclwin.st
- *
- * Classes to create and control the windowing interface
- *
- * Julian Barkway (c) September 1994 All rights reserved.
- *
- * (Based on stdwin.st by Timothy Budd)
- *
- * v3.1.0 - Initial release
- * v3.1.1 - Changed to ensure correct system menu highlighting
- * when no windows are open.
- * v3.1.2 - No longer crashes when 'printer print:' invoked with no Workspace.
- * - Changed to allow the Workspace window to be restored after
- * being closed.
- * - Pixel line length can now be specified for text-based panes.
- * - Sundry tidying-up of code.
- * v3.1.3 - Pop-up menu objects removed from global menus array. Global added to
- * track pop-up menu numbers.
- * - Added Smalltalk: getVersion to return the version number as a string.
- * - Menus now referred to by direct pointers to their internal representation
- * instead of array indices.
- * v3.1.5 - Added pop-up menu for Workspace window
- * - 'Inspect it' added to System menu.
- * - Windows can be non-closeable.
- * - Multiple workspaces supported; opening a text file automatically creates
- * a new workspace for the file; original workspace is now a non-closeable
- * 'system transcript' window.
- * - Command-key equivalents supported in menus.
- * - Menus now support method selectors as well as blocks for the 'action:' parameter.
- * - Panes now support method selectors in place of blocks for mouse actions.
- * - Pane now directly supports pop-up menus (to use: override Pane>>createPopUpMenu,
- * place the method selectors you wish to use as symbols in your menu definition
- * then set the menu's owner to the object defining these selectors).
- * - Panes now have 'parent' as an instance variable to assist in inter-pane co-ordination
- * for objects that have more than one pane. (To use: set the pane's parent to the
- * co-ordinating object and use it to route inter-pane message sends).
- * - SelectListPane now supports an assignable source Collection and protocol to support:
- * • sending a message to the selected item
- * • sending a message to another object with the selected item as a parameter
- * • evaluating a block with the selected item as a parameter.
- * ***
- Class UserInterface Object saveWS nextItemNumber itemList " - changed for v3.1.2 "
- Class Window Object number title menus size position panes paneNumber mainPane goAwayBoxPresent
- Class WorkspaceWindow Window " - class added for v3.1.2 - changed for v3.1.5"
- Class SystemTranscriptWindow WorkspaceWindow
- Class WindowPane Object panePtr number type lineLength parentWindow bounds sizing b1Action b2Action b1DoubleClick owner parent pMenu
- Class TextPane WindowPane text fontName fontSize typeFace selectRange file
- Class SelectListPane TextPane selection collection
- Class GraphicsPane WindowPane
- Class EventManager Process responses
- Class Menu Object menuPtr number title itemtitles items enablestatus numItems shortcuts owner
- Class PopUpMenu Menu
- Class Cursor Object cursPtr
-
- *
- * Dictionary and List methods added for v3.1.5 to support SelectListPanes
- *
- Methods Dictionary 'enumerating'
- printString
- | s |
- s <- self class printString , ' ('.
- self binaryDo: [:x :y | s <- s , (x printString) , ' -> ',
- (y printString) , newLine ].
- s <- s , ')'.
- ^ s
- |
- asFormattedText
- " Return ourselves as a formatted list of key values "
- | txt |
- txt <- ''.
- self binaryDo: [:a :b |
- txt <- txt , (a asString) , newLine
- ].
- ^ txt
- |
- findText: theText
- " Match theText to a key and return the associated object "
- | sym |
- sym <- theText asSymbol.
- self binaryDo: [:a :b |
- (sym = a) ifTrue: [
- ^ b
- ]
- ].
- ]
-
- Methods List 'enumerating'
- newDo: aBlock
- | aLink |
- " For each link, perform aBlock using the link as an argument "
- aLink <- links.
- [ aLink notNil ] whileTrue: [
- aBlock value: aLink.
- aLink <- aLink next
- ]
- |
- asFormattedText
- " Return ourselves as a formatted list of key values "
- | txt |
- txt <- ''.
- (self links) binaryDo: [:k :v |
- txt <- txt , k , newLine
- ].
- ^ txt
- |
- findText: theText
- ^ self links at: theText ifAbsent: [ ^ nil ].
- ]
-
- Methods List 'assigning'
- links: aLink
- links <- aLink
- |
- addFirstLink: aLink
- (links notNil) ifTrue: [
- aLink link: links.
- links <- aLink
- ]
- ifFalse: [
- aLink link: nil.
- links <- aLink.
- listEnd <- links
- ]
- |
- addLastLink: aLink
- (links isNil)
- ifTrue: [ self addFirstLink: aLink ]
- ifFalse: [
- listEnd link: aLink.
- listEnd <- listEnd next
- ]
- ]
-
- Methods Link 'accessing'
- key
- ^ key
- ]
-
- Methods Window 'all'
- new
- title <- ''.
- menus <- List new.
- panes <- Array new: 15.
- paneNumber <- 0.
- goAwayBoxPresent <- true. "Line added for v3.1.5"
- ^ self allocateSlot
- |
- allocateSlot
- " Allocate a slot in the 'windows' global array. Moved out of 'new'
- to allow standalone access for v3.1.2 "
- (1 to: 15) do: [:i | (windows at: i) isNil
- ifTrue: [ windows at: i put: self.
- number <- i. ^ self ]
- ]
- |
- attachPane: pane
- paneNumber <- paneNumber + 1.
- panes at: paneNumber put: pane.
- mainPane <- pane.
- ^ paneNumber
- |
- attachMenu: menu
- menus addLast: menu.
- <162 number 2 (menu menuPtr)>
- |
- detachMenu: menu
- <162 number 3 (menu menuPtr)>
- |
- activate
- activeWindow <- self
- |
- deactivate
- ^ nil
- |
- mainPane
- ^ mainPane
- |
- panes
- ^ panes
- |
- drawEvent
- " if no panes, do nothing otherwise let each pane draw itself "
- (paneNumber == 0) ifTrue: [
- ^ nil
- ]
- ifFalse: [
- (1 to: paneNumber) do: [ :i |
- (panes at: i) draw
- ]
- ]
- |
- mouseMoveTo: mouseLocation
- " mouse moved with button down "
- ^ nil
- |
- mouseDownAt: mouseLocation button: theButton
- " if no panes, do nothing otherwise let the appropriate pane handle the event "
- (paneNumber == 0) ifTrue: [
- ^ nil
- ]
- ifFalse: [
- (1 to: paneNumber) do: [ :i |
- ((panes at: i) mouseDownAt: mouseLocation button: theButton)
- ifTrue: [
- ^ nil
- ]
- ].
- ^ nil
- ]
- |
- mouseUpAt: mouseLocation
- " mouse up "
- ^ nil
- |
- command: n
- (n = 1) ifTrue: [ self close ]
- |
- moved
- position <- <161 number 7>
- |
- reSized
- size <- <161 number 6>
- |
- position
- ^ position
- |
- size
- ^ size
- |
- number
- ^ number
- |
- title
- ^ title
- |
- open
- " open our window, unless already opened "
- <160 number 1 title 0>.
- menus do: [:m | <162 number 2 (m menuPtr)> ].
- userInterface addToWindowsMenu: self.
- self reSized.
- self moved
- |
- openAt: aPosition withSize: aSize
- " open our window, unless already opened - changed for v3.1.5"
- <160 number 2 title 0 (aPosition x) (aPosition y) (aSize x) (aSize y) 0>.
- self open
- |
- openNoGoAwayWindowAt: aPosition withSize: aSize
- " open the window without a 'go away' box - added for v3.1.5"
- <160 number 2 title 0 (aPosition x) (aPosition y) (aSize x) (aSize y) 1>.
- self open
- |
- select
- <161 number 8>.
- self activate
- |
- wantsSave
- ^ <161 number 9>
- |
- charTyped: c
- smalltalk beep
- |
- title: text
- title <- text.
- <161 number 10 title>
- |
- close
- " close up shop "
- <161 number 1>.
- windows at: number put: nil.
- userInterface removeFromWindowsMenu: self
- |
- saveState
- " Save the state of system items (i.e. text that has been
- entered by the user) which are not represented by LSt objects "
- panes do: [:p |
- p notNil ifTrue: [
- p saveState
- ]
- ]
- |
- restoreState
- " Restore the state of this window and all its panes
- after loading a new image file "
- self openAt: position withSize: size.
- panes do: [:p |
- p notNil ifTrue: [
- p restoreState
- ]
- ]
- ]
-
- Methods WorkspaceWindow 'all' " Class added for v3.1.2, modified for v3.1.5 "
- create
- self create: 'Workspace'
- |
- create: windowTitle
- | maxW maxH |
- maxW <- (smalltalk getMaxScreenArea) right.
- maxW <- 500 min: (maxW - 50).
- maxH <- (smalltalk getMaxScreenArea) bottom.
- maxH <- 300 min: (maxH - 50).
- self title: windowTitle;
- openAt: (0@0) withSize: (maxW@maxH). " (0@0) = system places window "
- TextPane new;
- boundsFrom: (-1 @ -1) to: (size + (1 @ 1));
- owner: self;
- attachTo: self;
- button2Action: #pMenuSelect:.
- |
- pMenuSelect: p
- systemMenu popUpAt: p
- "
- ""
- "" The following two methods are now redundant - v3.1.5
- "" close
- "" self saveState.
- "" userInterface saveWorkspace.
- "" super close.
- ""
- ""|
- "" restoreWorkspace
- "" self allocateSlot.
- "" self restoreState.
- "
- ]
-
- *
- * SystemTranscriptWindow is an ever-present workspace which can't be closed.
- *
- Methods SystemTranscriptWindow 'all' " Class added for v3.1.5 "
- create
- | maxW maxH |
- maxW <- (smalltalk getMaxScreenArea) right.
- maxW <- 500 min: (maxW - 50).
- maxH <- (smalltalk getMaxScreenArea) bottom.
- maxH <- 300 min: (maxH - 50).
- self title: 'System Transcript'.
- self openNoGoAwayWindowAt: (0@0) withSize: (maxW@maxH).
- TextPane new;
- boundsFrom: (-1 @ -1) to: (size + (1 @ 1));
- owner: self;
- button2Action: #showSystemMenuAt:;
- attachTo: self;
- print: 'Welcome to Little Smalltalk ' , (smalltalk getVersion) ,
- newLine , newLine.
- ]
-
- Methods WindowPane 'all'
- new
- bounds <- Rectangle new.
- lineLength <- 0.
- |
- initialise " Added for v3.1.5 "
- self createPopUpMenu.
- self button2Action: #pMenuSelect:
- |
- pMenuSelect: aPoint " Added for v3.1.5 "
- pMenu notNil ifTrue: [
- pMenu popUpAt: aPoint
- ]
- |
- createPopUpMenu " Added for v3.1.5 "
- " Overridden by subclasses "
- pMenu <- nil
- |
- " Sizing options: 0 - axis is rigid, 1 - axis is elastic "
- attachTo: aWindow withType: theType andSizing: aPoint
- type <- theType.
- sizing <- aPoint.
- panePtr <- < 168 1 (aWindow number) theType
- (bounds upperLeft x)
- (bounds upperLeft y)
- (bounds bottomRight x)
- (bounds bottomRight y)
- (aPoint x) (aPoint y)
- lineLength >.
- number <- (aWindow attachPane: self).
- parentWindow <- aWindow.
- self initialise.
- ^ panePtr
- |
- boundsFrom: topLeft to: bottomRight
- bounds upperLeft: topLeft.
- bounds bottomRight: bottomRight
- |
- type: theType " 1 - text, 2 - select, 3 - graphics "
- type <- theType
- |
- parent: anObject
- " The pane's parent is the object responsible for this pane and those related to it "
- parent <- anObject
- |
- parent
- ^ parent
- |
- owner: anObject
- " The pane's owner is the object which defines the pane's menu and mouse-button methods "
- owner <- anObject
- |
- activate
- ^ nil
- |
- deactivate
- ^ nil
- |
- size
- ^ <168 2 panePtr>
- |
- position
- ^ nil
- |
- reSized
- ^ nil
- |
- draw
- ^ nil
- |
- mouseDownAt: mouseLocation button: theButton
- " Changed to allow double clicks for v3.1.2 "
- (bounds contains: mouseLocation) ifFalse: [
- ^ false
- ]
- ifTrue: [
- (theButton == 1) ifTrue: [
- (eventManager isDoubleClick) ifTrue: [
- (b1DoubleClick notNil) ifTrue: [
- self privatePerformAction: b1DoubleClick at: mouseLocation
- ]
- ]
- ifFalse: [
- (b1Action notNil) ifTrue: [
- self privatePerformAction: b1Action at: mouseLocation ]
- ]
- ].
- (theButton == 2) ifTrue: [
- (b2Action notNil) ifTrue: [
- self privatePerformAction: b2Action at: mouseLocation
- ]
- ].
- ^ true
- ]
- |
- privatePerformAction: action at: mouseLocation
- | a |
- a <- Array new: 2;
- at: 1 put: owner;
- at: 2 put: mouseLocation.
- smalltalk perform: action withArguments: a ifError:
- [ smalltalk showMessage: 'Invalid action for mouse button event' ]
- |
- button1Action: aSelector
- b1Action <- aSelector
- |
- button1DoubleClick: aSelector
- b1DoubleClick <- aSelector
- |
- button2Action: aSelector
- b2Action <- aSelector
- |
- saveState
- " Handled by sub-classes "
- ^ nil
- |
- restoreState
- " Handled by sub-classes "
- ^ nil
- ]
-
- Methods TextPane 'all'
- new
- super new.
- file <- nil
- |
- isTextPane
- ^ true
- |
- file
- "Method added for v3.1.5"
- ^ file
- |
- " Added for v3.1.2 "
- attachTo: aWindow withSizing: aPoint andLineLength: anInteger
- lineLength <- anInteger.
- panePtr <- super attachTo: aWindow withType: 1 andSizing: aPoint.
- |
- attachTo: aWindow withSizing: aPoint
- lineLength <- 2000.
- panePtr <- super attachTo: aWindow withType: 1 andSizing: aPoint.
- |
- attachTo: aWindow
- lineLength <- 2000.
- panePtr <- super attachTo: aWindow withType: 1 andSizing: (1@1).
- |
- text
- " read updated text and store it"
- ^ text <- <165 panePtr 1>
- |
- selectedText
- " read selected text and store it"
- selectRange <- self getSelectionRange.
- ^ text <- <165 panePtr 2>
- |
- replaceAllTextWith: newText
- <165 panePtr 3 newText>
- |
- clearAllText
- <165 panePtr 4>
- |
- print: text
- <166 panePtr text>
- |
- draw
- "redraw pane"
- <168 4 panePtr>.
- <168 3 panePtr>.
- <168 5 panePtr>
- |
- saveContentsTo: aFileName withType: aFileType
- | f |
- f <- File new;
- name: aFileName;
- open: 'wb' withType: aFileType.
- watchCursor show.
- <206 panePtr 1 (f number)>.
- f close.
- smalltalk setDefaultCursor
- |
- saveContents: fileType | fname |
- "Functionality moved to UserInterface>>saveText: - v3.1.5"
- ^ nil
- " fname <- smalltalk askNewFile: 'Text file:'.
- "" (fname notNil) ifTrue: [
- "" self saveContentsTo: fname withType: fileType.
- "" ^ true
- "" ]
- "" ifFalse: [
- "" ^ false
- "" ]
- "
- |
- loadContentsFrom: aFileName | f |
- "Modified for v3.1.5"
- f <- File new;
- name: aFileName;
- open: 'rb'.
- watchCursor show.
- <206 panePtr 0 (f number)>.
- f close.
- smalltalk setDefaultCursor.
- file <- aFileName.
- |
- loadContents: fileType | fname |
- "Functionality moved to UserInterface>>openTextFile: - v3.1.5"
- ^ nil
- " fname <- smalltalk askFile: 'Text file:' withFilter: fileType.
- "" (fname notNil) ifTrue: [
- "" self loadContentsFrom: fname.
- "" ^ true
- "" ]
- "" ifFalse: [
- "" ^ false
- "" ]
- "
- |
- getSelectionRange
- " Return the current selection range as a point where x = start and y = end
- of range "
- ^ <165 panePtr 9>
- |
- setSelectionRangeFrom: startCharPos to: endCharPos
- " set the selection range to the given start and end character positions "
- <165 panePtr 8 startCharPos endCharPos>
- |
- scrollToSelection
- " Ensure that the current selection is visible within the text pane"
- <165 panePtr 10>
- |
- font: aFontName
- fontName <- aFontName.
- <165 panePtr 5 aFontName>
- |
- fontSize: aNumber
- fontSize <- aNumber.
- <165 panePtr 6 aNumber>
- |
- typeFace: aNumber " 1 - plain, 2 - bold, 3 - italic, 4 - underline "
- typeFace <- aNumber.
- <165 panePtr 7 aNumber>
- |
- saveState
- self text.
- selectRange <- self getSelectionRange
- |
- restoreState
- " Restore the state of this pane after loading a new image file and
- re-draw any text "
- panePtr <- < 168 1 (parentWindow number) type
- (bounds upperLeft x)
- (bounds upperLeft y)
- (bounds bottomRight x)
- (bounds bottomRight y)
- (sizing x) (sizing y) >.
- (fontName notNil) ifTrue: [
- self font: fontName
- ].
- (fontSize notNil) ifTrue: [
- self fontSize: fontSize
- ].
- (typeFace notNil) ifTrue: [
- self typeFace: typeFace
- ].
- self print: text.
- (selectRange notNil) ifTrue: [
- ((selectRange x) ~= (selectRange y)) ifTrue: [
- self setSelectionRangeFrom: (selectRange x) to: (selectRange y).
- self scrollToSelection
- ]
- ]
- ]
-
- Methods SelectListPane 'all'
-
- isTextPane
- ^ false
- |
- openOn: aCollection in: aWindow withSizeFrom: topLeft to: bottomRight
- collection <- aCollection.
- self boundsFrom: topLeft to: bottomRight;
- attachTo: aWindow withSizing: (0 @ 0)
- |
- attachTo: aWindow withSizing: aPoint
- panePtr <- super attachTo: aWindow withType: 2 andSizing: aPoint
- |
- collection: aCollection
- collection <- aCollection
- |
- withSelectedItemSend: aSelector to: anObject
- " Send aSelector to anObject, using the selected item as an argument "
- | item a |
- item <- (collection findText: (self getSelectedKey)).
- item notNil ifTrue: [
- a <- Array new: 2.
- a at: 1 put: anObject; at: 2 put: item.
- smalltalk perform: aSelector withArguments: a
- ]
- ifFalse: [
- ^ nil
- ]
- |
- sendToSelectedItem: aSelector
- " Send aSelector to the currently selected item "
- | item a |
- item <- (collection findText: (self getSelectedKey)).
- item notNil ifTrue: [
- a <- Array new: 1.
- a at: 1 put: item.
- smalltalk perform: aSelector withArguments: a
- ]
- ifFalse: [
- ^ nil
- ]
- |
- evaluateForSelectedItem: aBlock
- " Evaluate aBlock with the selected item as parameter "
- | item |
- item <- (collection findText: (self getSelectedKey)).
- aBlock value: item
- |
- getSelectedKey
- | t |
- " Strip <cr> from selected text and return as a key "
- t <- self selectedText.
- ^ t copyFrom: 1 to: ((t size) - 1).
- |
- setText
- " Display the pane's collection as a selectable list "
- self clearAllText; text: (collection asFormattedText)
- |
- text: t
- text <- t.
- self print: text
- |
- close
- pMenu dispose
- ]
-
- Methods GraphicsPane 'all'
- isTextPane
- ^ false
- |
- attachTo: aWindow withSizing: aPoint
- panePtr <- super attachTo: aWindow withType: 3 andSizing: aPoint
- |
- startDrawing
- <168 4 panePtr>
- |
- endDrawing
- <168 5 panePtr>
- |
- draw
- " done by subclasses "
- ^ nil
- |
- at: x and: y print: text
- <190 x y text>
- |
- saveState
- " Should save graphics in some way that allows them to be
- easily restored later "
- ^ nil
- |
- restoreState
- " Restore the state of this pane after loading a new image file and
- re-draw any graphics "
- super restoreState.
- self draw
- ]
-
- Methods Menu 'all'
- new "Modified for v3.1.5"
- numItems <- 0.
- items <- Array new: 0.
- itemtitles <- Array new: 0.
- enablestatus <- Array new: 0.
- shortcuts <- Array new: 0.
- (1 to: 15) do: [:i | (menus at: i) isNil
- ifTrue: [ menus at: i put: self.
- number <- i. ^ self ] ]
- |
- number
- ^ number
- |
- menuPtr
- ^ menuPtr
- |
- owner: anObject
- "Added for v3.1.5"
- owner <- anObject
- |
- owner
- "Added for v3.1.5"
- ^ owner
- |
- addSeparator "Note: Macintosh specific"
- self addItem: '-' action: [ ^ nil ].
- self disableItem: numItems
- |
- addItem: name action: aBlock
- items <- items with: aBlock.
- itemtitles <- itemtitles with: name.
- enablestatus <- enablestatus with: true.
- shortcuts <- shortcuts with: -1.
- <181 menuPtr name nil>.
- numItems <- numItems + 1
- |
- addItem: name action: aBlock withShortcut: aCharacter
- "Added for v3.1.5"
- items <- items with: aBlock.
- itemtitles <- itemtitles with: name.
- enablestatus <- enablestatus with: true.
- shortcuts <- shortcuts with: aCharacter.
- <181 menuPtr name (aCharacter asInteger)>.
- numItems <- numItems + 1
- |
- removeItem: anItemNumber
- "Modified for v3.1.5"
- (anItemNumber to: (numItems - 1)) do: [:i | "Shift up array elements to close gap"
- items at: i put: (items at: (i + 1)).
- itemtitles at: i put: (itemtitles at: (i + 1)).
- enablestatus at: i put: (enablestatus at: (i + 1)).
- shortcuts at: i put: (shortcuts at: (i + 1))
- ].
- <184 menuPtr 2 anItemNumber>.
- numItems <- numItems - 1
- |
- enableItem: n
- enablestatus at: n put: true.
- <182 menuPtr n 1 1>
- |
- disableItem: n
- enablestatus at: n put: false.
- <182 menuPtr n 1 0>
- |
- selectItem: n inWindow: w
- " execute the selected menu item "
- (items at: n) value: w
- |
- selectItem: n
- | item |
- item <- items at: n.
- (item respondsTo: #blockContext:) ifTrue: [
- item value: nil
- ]
- ifFalse: [
- self performItemAction: item
- ]
- |
- performItemAction: action
- "Added for v3.1.5"
- | a |
- a <- Array new: 1.
- a at: 1 put: owner.
- smalltalk perform: action withArguments: a ifError:
- [ smalltalk showMessage: 'Invalid action for selected menu option' ]
- |
- popUpAt: aPoint
- "Added for v3.1.5"
- | sel item |
- "Display this menu as a pop-up menu at 'aPoint' "
- smalltalk setDefaultCursor.
- sel <- <183 menuPtr (aPoint y) (aPoint x)>.
- (sel ~= 0) ifTrue: [
- self selectItem: sel
- ]
- |
- title: aString
- " give the title to a menu item"
- title <- aString
- |
- create
- "create menu"
- menuPtr <- <180 number title 0> "Method changed for v3.1.3"
- |
- dispose
- <184 menuPtr 1>
- |
- restoreItems
- " Add all the existing items and set status accordingly "
- (1 to: items size) do:
- [:i | <181 menuPtr (itemtitles at: i) nil>.
- (enablestatus at: i)
- ifFalse: [ self disableItem: i]]
- |
- restoreState
- " Restore the state of this menu after loading a new image file "
- self create.
- self restoreItems
- ]
-
- Methods PopUpMenu 'all'
- new "Super method overridden for v3.1.3, modified for v3.1.5"
- numItems <- 0.
- items <- Array new: 0.
- itemtitles <- Array new: 0.
- enablestatus <- Array new: 0.
- shortcuts <- Array new: 0.
- |
- create "Method changed for v3.1.3"
- "create menu"
- menuPtr <- <180 nextPopMenuNum title 1>.
- number <- nextPopMenuNum.
- nextPopMenuNum <- nextPopMenuNum + 1.
- "|"
- "" "Methods eliminated for v3.1.5 - now inherited"
- " popUpAt: aPoint | sel item |
- "" smalltalk setDefaultCursor.
- "" sel <- <183 menuPtr (aPoint y) (aPoint x)>.
- "" (sel ~= 0) ifTrue: [
- "" item <- items at: sel.
- "" item value
- "" ]
- ""
- ""|
- "" restoreState
- " " Restore the state of this pop-up menu after loading a new image file "
- " self create.
- "" self restoreItems
- "
- ]
-
- Methods EventManager 'all'
- new
- "Create an array containing methods to be executed on receiving each event"
- responses <- Array new: 24.
- responses at: 1 put: [:w | w activate ].
- " Where key presses are concerned, TextEdit now does the hard work. So,
- unless anyone has a better idea, we will ignore key presses for now. "
- responses at: 2 put: [:w | w <- nil ].
- " responses at: 2 put: [:w | w charTyped: (Char new; value: <171 4>) ]."
- responses at: 3 put: [:w | w command: <171 9> ].
- responses at: 4 put: [:w |
- w mouseDownAt: self mouseLocation button: (self mouseButton) ].
- responses at: 5 put: [:w | w mouseMoveTo: self mouseLocation ].
- responses at: 6 put: [:w | w mouseUpAt: self mouseLocation ].
- responses at: 7 put: [:w | self eventMenu
- " selectItem: self menuItem inWindow: w ]."
- selectItem: self menuItem ].
- responses at: 8 put: [:w | w reSized ].
- responses at: 9 put: [:w | w moved ].
- responses at: 10 put: [:w | smalltalk updateWindows ].
- self newPartTwo
- |
- newPartTwo
- "Continuation of the above method due to limits on bytecode array sizes"
- responses at: 11 put: [:w | scheduler quit ]. "Was timer event"
- responses at: 12 put: [:w | w deactivate ].
- responses at: 13 put: [:w | smalltalk processEvent ]. "Externally generated event (AppleEvent)"
- responses at: 14 put: [:w | w deactivate ]. "Non-ASCII key event"
- responses at: 15 put: [:w | w deactivate ]. "Lost selection"
- responses at: 16 put: [:w | w close ]
- |
- eventWindow | w | "Which window is event from?"
-
- "Changed to allow for legitimate cases when window is not"
- "found (e.g. menu selection made with no open windows or a window"
- "has been selected that is not ours"
-
- w <- <171 1>.
- (w = 0) ifTrue: [
- ^ 0
- ]
- ifFalse: [
- ^ windows at: w
- ]
- |
- eventMenu | m |
- ^ menus at: <171 2>. "Which menu is event from?"
- |
- menuItem
- ^ <171 3>
- |
- mouseLocation
- " return the current location of the mouse "
- ^ <172 1>
- |
- mouseButton
- " Return the number of the mouse button pressed "
- ^ <171 6>
- |
- mouseClicks
- " Return the number of clicks of the mouse button - added for v3.1.2"
- ^ <171 7>.
- |
- isDoubleClick
- " Return true if a double click has been detected - added for v3.1.2"
- ^ (self mouseClicks = 2)
- |
- execute | i w |
- " process one event "
- i <- <170>. (i = 0)
- ifFalse: [ "Changed to allow for eventWindow returning zero"
- w <- self eventWindow.
- activeWindow <- w.
- (w = 0) ifTrue: [
- (i = 11) ifTrue: [ "Trap quit command"
- (responses at: i) value: nil
- ].
- (i = 7) ifTrue: [ "Trap menu selection with no open windows"
- (responses at: i) value: nil
- ] "Other possibility is that window is not ours"
- ] " so we ignore it"
- ifFalse: [
- (responses at: i) value: self eventWindow
- ]
- ]
- ]
- *
- * Following class extensively modified for v3.1.5
- *
- Methods UserInterface 'all'
- browseClasses
- | b |
- b <- Browser new; open.
- |
- interpretFile
- | f |
- f <- (smalltalk askFile: 'file name:').
- (f notNil) ifTrue: [
- smalltalk interpretFile: f
- ]
- |
- saveImage
- | f |
- [
- windows do: [:w |
- w notNil ifTrue: [ w saveState ]
- ].
- f <- (smalltalk askNewFile: 'Image file:').
- watchCursor show.
- smalltalk saveImage: f; setDefaultCursor
- ] fork
- |
- saveText
- | fname pane |
- pane <- activeWindow mainPane.
- fname <- pane file.
- fname isNil ifTrue: [
- self saveTextAs
- ]
- ifFalse: [
- pane saveContentsTo: fname withType: 1
- ]
- |
- saveTextAs
- | fname |
- fname <- smalltalk askNewFile: 'Text file:'.
- (fname notNil) ifTrue: [
- activeWindow mainPane saveContentsTo: fname withType: 1
- ]
- |
- openTextFile
- | fname |
- fname <- smalltalk askFile: 'Text file:' withFilter: 1.
- (fname notNil) ifTrue: [
- self openNamedTextFile: fname
- ]
- |
- printIt
- | p sel |
- [
- p <- activeWindow mainPane.
- sel <- p getSelectionRange.
- p print: (p selectedText value asString) , newLine.
- p setSelectionRangeFrom: (sel y) to: 32767
- ] fork
- |
- doIt
- [
- activeWindow mainPane selectedText execute
- ] fork
- |
- inspectIt
- ((activeWindow mainPane) selectedText , ' inspect') execute
- |
- newWorkspace
- WorkspaceWindow new; create
- |
- openNamedTextFile: fname
- | ws |
- ws <- WorkspaceWindow new; create: (smalltalk trimFileName: fname).
- (ws mainPane) loadContentsFrom: fname
- |
- makeSystemMenu " Changed for v3.1.5"
- systemMenu isNil ifTrue: [
- systemMenu <- Menu new; title: 'System'; owner: self; create.
- systemMenu
- addItem: 'Browser'
- action: #browseClasses
- withShortcut: $B;
- addSeparator;
- addItem: 'Interpret File...'
- action: #interpretFile;
- addItem: 'Save image...'
- action: #saveImage;
- addSeparator;
- addItem: 'Save'
- action: #saveText
- withShortcut: $S;
- addItem: 'Save As...'
- action: #saveTextAs;
- addItem: 'Open Text...'
- action: #openTextFile withShortcut: $O;
- addSeparator;
- addItem: 'Print It'
- action: #printIt
- withShortcut: $P;
- addItem: 'Do It'
- action: #doIt
- withShortcut: $D;
- addItem: 'Inspect It'
- action: #inspectIt
- withShortcut: $I;
- addSeparator;
- addItem: 'New Workspace'
- action: #newWorkspace
- withShortcut: $N
- ].
- |
- makeWindowsMenu
- windowsMenu <- Menu new; title: 'Windows'; create.
- nextItemNumber <- 0.
- itemList <- Array new: 15
- |
- addToWindowsMenu: aWindow
- (nextItemNumber == 0) ifFalse: [
- ((itemList at: nextItemNumber) == aWindow) ifTrue: [
- ^ nil " Already there..."
- ]
- ].
- windowsMenu addItem: (aWindow title)
- action: [:w | (itemList at: (eventManager menuItem)) select ].
- nextItemNumber <- nextItemNumber + 1.
- itemList at: nextItemNumber put: aWindow.
- self checkSystemMenu
- |
- removeFromWindowsMenu: aWindow | wmi |
- (1 to: nextItemNumber) do: [ :i | "Find the window in the list"
- ((itemList at: i) == aWindow) ifTrue: [
- wmi <- i
- ]
- ].
- windowsMenu removeItem: wmi.
- (wmi to: nextItemNumber - 1) do: [:i | "Shift up array elements to close gap"
- itemList at: i put: (itemList at: (i + 1))
- ].
- nextItemNumber <- nextItemNumber - 1.
- self checkSystemMenu
- |
- makeWorkspace " Functionality moved to class WorkspaceWindow - v3.1.2 "
- workspace <- WorkspaceWindow new.
- workspace attachMenu: systemMenu; attachMenu: windowsMenu.
- systemMenu disableItem: 12.
- |
- saveWorkspace " Added for v3.1.2 "
- saveWS <- workspace.
- workspace <- nil.
- printer <- nil.
- |
- restoreWorkspace " Added for v3.1.2 "
- workspace <- saveWS.
- workspace restoreWorkspace.
- printer <- workspace mainPane.
- |
- makeTranscript
- systemTranscript <- SystemTranscriptWindow new;
- create;
- attachMenu: systemMenu;
- attachMenu: windowsMenu.
- |
- checkSystemMenu
- " Disable certain menu items when there are no windows open. Enable
- them when there are. Invoked whenever windows are opened or closed.
- - added for v3.1.1"
- ^ nil. " No longer needed as of v3.1.5"
-
- (nextItemNumber = 0) ifTrue: [
- systemMenu disableItem: 6;
- disableItem: 7;
- disableItem: 9;
- disableItem: 10;
- enableItem: 12
- ]
- ifFalse: [
- systemMenu enableItem: 6;
- enableItem: 7;
- enableItem: 9;
- enableItem: 10.
- workspace isNil ifTrue: [
- systemMenu enableItem: 12
- ]
- ifFalse: [
- systemMenu disableItem: 12
- ]
- ]
- ]
-
- Methods Smalltalk 'doit'
- error: aString | ew |
- " print a message, and remove current process "
- " scheduler currentProcess trace. "
- self showMessage: aString.
- (scheduler currentProcess) terminate
- ]
-
- Methods Scheduler 'get commands'
- initialize
- "Modified for v3.1.5"
- (systemTranscript isNil) ifTrue: [
- watchCursor fetchNamedCursor: 'watch'.
- userInterface makeSystemMenu.
- userInterface makeWindowsMenu.
- userInterface makeTranscript
- ].
- printer <- systemTranscript mainPane.
- eventManager <- EventManager new.
- scheduler addProcess: eventManager
- |
- quit
- " all done - really quit "
- " should probably verify first "
- notdone <- false
- ]
- *
- * initialization code
- * this is executed once, by the initial image maker
- *
- *
- Methods UndefinedObject 'initial image'
- createGlobals
- " create global variables in initial image "
- true <- True new.
- false <- False new.
- smalltalk <- Smalltalk new.
- files <- Array new: 15.
- classes <- Dictionary new. " create a dictionary of classes "
- symbols binaryDo: [:x :y |
- (y class == Class)
- ifTrue: [ classes at: x put: y ] ].
- self createGlobalsPart2
- |
- createGlobalsPart2
- printer <- nil.
- windows <- Array new: 15.
- menus <- Array new: 15.
- scheduler <- Scheduler new.
- userInterface <- UserInterface new.
- eventManager <- nil.
- " workspace <- nil." "Removed for v3.1.5"
- systemTranscript <- nil.
- activeWindow <- nil.
- nextBrowserNum <- 1.
- nextWkSpaceNum <- 1.
- newLine <- 13 asCharacter.
- watchCursor <- Cursor new.
- systemMenu <- nil.
- windowsMenu <- nil.
- activeWindow <- nil.
- nextPopMenuNum <- 0 "Global added for v3.1.3"
- |
- initialize | aBlock |
- " initialize the initial object image "
- self createGlobals.
- " create the initial system process "
- " note the delayed recursive call "
- aBlock <- [ files do: [:f | f notNil ifTrue: [ f open ]].
- menus do: [:m | m notNil ifTrue: [ m restoreState ]].
- windows do: [:w | w notNil ifTrue: [ w restoreState ]].
- systemProcess <- aBlock newProcess.
- scheduler run ].
- systemProcess <- aBlock newProcess.
- File new;
- name: 'systemImage';
- open: 'wb' withType: 2;
- saveImage;
- close
- ]
-
- Methods String 'test'
- print
- ^ printer print: self
- ]
-
- Methods Smalltalk 'interface'
- getVersion "Added for v3.1.3"
- ^ <254>
- |
- showMessage: aString "Added for v3.1.2"
- ^ <204 aString>
- |
- getPrompt: aString
- ^ <201 aString ''>
- |
- askNewFile: prompt
- " ask for a new file name "
- ^ <203 prompt '' 1 0>
- |
- askFile: prompt
- "ask for a file name but don't filter out unwanted file types"
- ^ <203 prompt '' 0 0>
- |
- askFile: prompt withFilter: filter | i |
- "ask for a file name, filtering out all types but 'filter'. Filter
- should be 1 or 2 according to the three available file types:
- 1 - Text (including saved workspaces)
- 2 - System Image "
- ^ <203 prompt '' 0 filter>
- |
- inquire: aString
- ^ <202 aString 1>
- |
- updateWindows "Re-draw all windows"
- windows do: [ :win |
- (win notNil)
- ifTrue: [
- win drawEvent
- ]
- ]
- |
- updateClassDictionary
- " Update the class dictionary. It's a bit wasteful
- creating a new Dictionary object every time, but
- the alternative is to check each class to see if
- it's new or not...."
- classes <- Dictionary new.
- symbols binaryDo: [:x :y |
- (y class == Class) ifTrue: [
- classes at: x put: y
- ]
- ]
- |
- getMaxScreenArea "Return a rect representing the max available screen area"
- ^ <167>
- |
- "
- processEvent: Process externally generated events
- - only event for now is Open Document so we do no event type checks.
- "
- processEvent | fullPath ft mp | "Changed for v3.1.3"
- fullPath <- <207>. " Get info from event - a file type and a full path "
- (fullPath notNil) ifTrue: [
- ft <- (fullPath copyFrom: 1 to: 1) asInteger.
- fullPath <- fullPath copyFrom: 2 to: (fullPath size).
- (ft = 2) ifTrue: [
- self showMessage:
- 'Cannot load new System Image whilst application is still running'
- ]
- ifFalse: [
- self processDroppedFile: fullPath
- ]
- ]
- |
- processDroppedFile: fullPath | s | "Method added for v3.1.3, modified for v3.1.5"
- s <- fullPath copyFrom: ((fullPath size) - 2) to: (fullPath size).
- (s = '.st') ifTrue: [
- self interpretFile: fullPath.
- ^ nil
- ]
- ifFalse: [
- userInterface openNamedTextFile: fullPath
- ].
- ^ nil
- |
- interpretFile: aFileName "Method added for v3.1.3"
- watchCursor show.
- File new; fileIn: aFileName.
- self updateClassDictionary; setDefaultCursor
- |
- trimFileName: aFileName "Method added for v3.1.5 - Mac specific!!!!"
- "Trim path info from fully qualified filename"
- | a |
- a <- (aFileName words: [:x | x ~= $: ]).
- ^ a at: (a size)
- ]
-
- Methods Point 'drawing'
- moveTo
- <192 2 (self x) (self y)>
- |
- drawPixel
- <192 3 (self x) (self y)>
- |
- lineTo
- <192 1 (self x) (self y)>
- ]
-
- Methods Rectangle 'drawing'
- frame
- <194 1 left top right bottom>
- |
- paint
- <194 2 left top right bottom>
- |
- erase
- <194 3 left top right bottom>
- |
- invert
- <194 4 left top right bottom>
- |
- shade: aPercent
- <195 1 left top right bottom aPercent>
- ]
-
- Methods Smalltalk 'beep'
- beep
- <205>
- ]
-
- Methods Circle 'drawing'
- frame
- <193 1 (center x) (center y) radius>
- ]
-
- Methods Cursor 'all'
- "
- The valid cursor names are:
- ibeam - standard text-editing cursor
- cross - cross-hairs
- plus - blocky '+' sign
- watch - standard 'busy' cursor
- arrow - default
- ClosedHand - a closed hand
- OpenHand - an open hand 'dragging' cursor
- Pen - a pen symbol
- The last three are defined in the resource fork. Extra cursors maybe added
- to the resource file and referenced by name in the same way.
- "
- fetchNamedCursor: aCursorName
- cursPtr <- <164 1 aCursorName>
- |
- show
- <164 2 cursPtr>
- ]
-
- Methods Smalltalk 'cursor'
- setDefaultCursor
- <164 3>
- ]
-